package com.kc.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kc.ExceptionHandler.UndowException;
import com.kc.bean.*;
import com.kc.config.UploadFileConfig;
import com.kc.mapper.ArticleMapper;
import com.kc.service.*;
import com.kc.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2019-10-22
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    private Logger logger = LoggerFactory.getLogger(ArticleServiceImpl.class);

    @Resource
    private ILableArticleService lableArticleService;

    @Resource
    private ILableService lableService;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private ResponesBean responesBean;

    @Autowired
    private UploadFileConfig uploadFileConfig;

    @Resource
    private ICommentService commentService;

    @Resource
    private IUserAccountService userAccountService;


    /**
     * 插入文章的接口，还有一个图片插入接口
     *
     * @param article
     * @return
     */
    @Transactional
    @Override
    public ResponesBean inster(Article article, String[] lable, String token) {
        try {
            Lable lable1 = new Lable();
            UserAccount account = new UserAccount();
            LableArticle lableArticle = new LableArticle();
            List<Lable> lableList = lableService.getLable(lable);
            int n = 0;

            account = userAccountService.getUserAccount(userAccountService.getAccount(token));
            article.setUserid(account.getUserId());
            article.setArtcileId(UuidCreate.getUUID());
            article.setPublisher(account.getUserNickname());

            //插入文章表、标签表以及标签文章表
            articleMapper.insert(article);

            for (String s : lable) {
                //插入前先进行判断是否已经有此标签存在.
                if (lableList != null) {
                    if (!lableList.get(n).getLableName().equals(s)) {
                        lable1.setLableName(s);
                        lableService.inster(lable1);
                        n++;
                    }
                } else {
                    lable1.setLableName(s);
                    lableService.inster(lable1);
                }
            }

            //暂时思路是重新获取当前第一个插入的lable的id，因为是自增的还没有其他思路去截取id放到文章标签表
//            int i = lableService.getlableId(lable1.getLableName()) - lable.length;
            List<Lable> list = lableService.getLable(lable);
            for (int k = 0; k < list.size(); k++) {
                lableArticle.setLableId(list.get(k).getLableId());
                lableArticle.setArticleId(article.getArtcileId());
                lableArticleService.inster(lableArticle);
            }
            responesBean.setAll(200, "文章发布成功", article);
            //新的文章插入便会放进去，使用redis集成的排序进行排行
            RedisUtil.Addtop(0, article.getArtcileId());
            return responesBean;
        } catch (NullPointerException e) {
            throw new UndowException("传输值为空");
        }
    }

    /**
     * 此为文件上传接口，负责文章发布的文件上传以及文章评论内容的文件上传。
     * 文件大小不得超过5MB
     *
     * @param file
     * @return
     */
    @Transactional
    @Override
    public ResponesBean editor(MultipartFile file, String AimsId, String EditorType) {
        //判断是否超过5MB
        if (file.getSize() > ((1048576 * 5))) {
            responesBean.setAll(400, "文件超过5MB，请重新选择", null);
        }
        String filetype = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));

        String FileName = UuidCreate.getUUID() + "/" + System.currentTimeMillis() + filetype;//数据库保存的名字
        String saveName = uploadFileConfig.getUploadFolder() + FileName;//文件上传的路径
        File update = new File(saveName);
        //查看目录是否存在不存在即创建一个新的目录
        if (!update.getParentFile().exists()) {
            update.getParentFile().mkdir();
        }
        try {
            file.transferTo(update);

            //判断是文章发布还是评论，请求不一样插入的表不一致
            if (EditorType.equals(ParamEnum.ArticleEditor)) {

                Article article = new Article();
                article.setImgPath(FileName);
                article.setArtcileId(AimsId);
                articleMapper.update(article, new UpdateWrapper<>());

            } else if (EditorType.equals(ParamEnum.CommentEditor)) {
                Comment comment = new Comment();
                comment.setArticleId(AimsId);
                comment.setFileName(FileName);
                commentService.updateComment(comment);
            }
            responesBean.setAll(200, "图片上传成功", saveName);
            return responesBean;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            logger.error("有属性为空请查看");
            throw new UndowException("要上传的文件为空请重新");
        }
        responesBean.setAll(400, "上传失败", null);
        return responesBean;
    }


    //热门排行接口

    /**
     * 暂时按照评论数以及
     *
     * @return
     */
    @Override
    public ResponesBean TopArticle() {
        Set<String> set = null;
        List<Article> articleList = new ArrayList<>();
        Article article = null;
        try {
            //获取redis实时排行的前5的文章
            set = RedisUtil.getTop(0, 5);
            for (String s : set) {
                article = articleMapper.getArticle(Wrappers.<Article>lambdaQuery().eq(Article::getTitle, s));
                articleList.add(article);
            }
            if (articleList.size() == 0) {
                responesBean.setAll(200, "没有文章", null);
            }
            responesBean.setAll(200, "排行如下", articleList);
            return responesBean;
        } catch (Exception e) {
            throw new UndowException(e.getMessage());
        }
    }

    @Override
    public int updateArticle(Article article) {
        UpdateWrapper<Article> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("artcile_id", article.getArtcileId());
        return articleMapper.update(article, updateWrapper);
    }

    @Resource
    private IClassificationService classificationServicel;

    /**
     * 查询文章且如果缓存中没有就存放到缓存里面时间30分钟
     *
     * @param ArticleId
     * @return
     */
    @Cacheable(value = "FindArticle", key = "")
    @Override
    public Map<String, Object> ViewArticle(String ArticleId) {

        Article article = null;
        List<Classification> classificationList = null;
        List<Comment> commentList = null;
        List<Lable> lableList = null;
        List<LableArticle> lableArticles = null;
        Map<String,Object> map = new HashMap<>();
        //查找出需要回显的文章
        try {

            article = articleMapper.getArticle(Wrappers.<Article>lambdaQuery().eq(Article::getArtcileId, ArticleId));

            if (article != null) {

                classificationList = classificationServicel.getClassification(article.getClassificationId());
                commentList = commentService.getComment(article.getArtcileId());
                lableArticles = lableArticleService.getLableArticle(article.getArtcileId());
                if (lableArticles.size()!=0){
                    lableList = lableService.getLableList(lableArticles);
                    map.put("Article",article);
                    map.put("Comment",commentList);
                    map.put("Lable",lableList);
                    return map;
                }
            }

        } catch (NullPointerException e) {
            throw new UndowException("传入的文章id为空" + e.getMessage());
        }
        return null;
    }

}
